//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension KinesisVideo {
    // MARK: Enums

    public enum APIName: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case getClip = "GET_CLIP"
        case getDashStreamingSessionUrl = "GET_DASH_STREAMING_SESSION_URL"
        case getHlsStreamingSessionUrl = "GET_HLS_STREAMING_SESSION_URL"
        case getImages = "GET_IMAGES"
        case getMedia = "GET_MEDIA"
        case getMediaForFragmentList = "GET_MEDIA_FOR_FRAGMENT_LIST"
        case listFragments = "LIST_FRAGMENTS"
        case putMedia = "PUT_MEDIA"
        public var description: String { return self.rawValue }
    }

    public enum ChannelProtocol: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case https = "HTTPS"
        case webrtc = "WEBRTC"
        case wss = "WSS"
        public var description: String { return self.rawValue }
    }

    public enum ChannelRole: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case master = "MASTER"
        case viewer = "VIEWER"
        public var description: String { return self.rawValue }
    }

    public enum ChannelType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fullMesh = "FULL_MESH"
        case singleMaster = "SINGLE_MASTER"
        public var description: String { return self.rawValue }
    }

    public enum ComparisonOperator: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case beginsWith = "BEGINS_WITH"
        public var description: String { return self.rawValue }
    }

    public enum ConfigurationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        public var description: String { return self.rawValue }
    }

    public enum Format: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case jpeg = "JPEG"
        case png = "PNG"
        public var description: String { return self.rawValue }
    }

    public enum FormatConfigKey: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case jpegQuality = "JPEGQuality"
        public var description: String { return self.rawValue }
    }

    public enum ImageSelectorType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case producerTimestamp = "PRODUCER_TIMESTAMP"
        case serverTimestamp = "SERVER_TIMESTAMP"
        public var description: String { return self.rawValue }
    }

    public enum MediaStorageConfigurationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        public var description: String { return self.rawValue }
    }

    public enum MediaUriType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fileUri = "FILE_URI"
        case rtspUri = "RTSP_URI"
        public var description: String { return self.rawValue }
    }

    public enum RecorderStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case success = "SUCCESS"
        case systemError = "SYSTEM_ERROR"
        case userError = "USER_ERROR"
        public var description: String { return self.rawValue }
    }

    public enum Status: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case creating = "CREATING"
        case deleting = "DELETING"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum StrategyOnFullSize: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case deleteOldestMedia = "DELETE_OLDEST_MEDIA"
        case denyNewMedia = "DENY_NEW_MEDIA"
        public var description: String { return self.rawValue }
    }

    public enum SyncStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case acknowledged = "ACKNOWLEDGED"
        case deleteFailed = "DELETE_FAILED"
        case deleting = "DELETING"
        case deletingAcknowledged = "DELETING_ACKNOWLEDGED"
        case inSync = "IN_SYNC"
        case syncFailed = "SYNC_FAILED"
        case syncing = "SYNCING"
        public var description: String { return self.rawValue }
    }

    public enum UpdateDataRetentionOperation: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case decreaseDataRetention = "DECREASE_DATA_RETENTION"
        case increaseDataRetention = "INCREASE_DATA_RETENTION"
        public var description: String { return self.rawValue }
    }

    public enum UploaderStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case success = "SUCCESS"
        case systemError = "SYSTEM_ERROR"
        case userError = "USER_ERROR"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ChannelInfo: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the signaling channel.
        public let channelARN: String?
        /// The name of the signaling channel.
        public let channelName: String?
        /// Current status of the signaling channel.
        public let channelStatus: Status?
        /// The type of the signaling channel.
        public let channelType: ChannelType?
        /// The time at which the signaling channel was created.
        public let creationTime: Date?
        /// A structure that contains the configuration for the SINGLE_MASTER channel type.
        public let singleMasterConfiguration: SingleMasterConfiguration?
        /// The current version of the signaling channel.
        public let version: String?

        @inlinable
        public init(channelARN: String? = nil, channelName: String? = nil, channelStatus: Status? = nil, channelType: ChannelType? = nil, creationTime: Date? = nil, singleMasterConfiguration: SingleMasterConfiguration? = nil, version: String? = nil) {
            self.channelARN = channelARN
            self.channelName = channelName
            self.channelStatus = channelStatus
            self.channelType = channelType
            self.creationTime = creationTime
            self.singleMasterConfiguration = singleMasterConfiguration
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case channelName = "ChannelName"
            case channelStatus = "ChannelStatus"
            case channelType = "ChannelType"
            case creationTime = "CreationTime"
            case singleMasterConfiguration = "SingleMasterConfiguration"
            case version = "Version"
        }
    }

    public struct ChannelNameCondition: AWSEncodableShape {
        /// A comparison operator. Currently, you can only specify the BEGINS_WITH operator, which finds signaling channels whose names begin with a given prefix.
        public let comparisonOperator: ComparisonOperator?
        /// A value to compare.
        public let comparisonValue: String?

        @inlinable
        public init(comparisonOperator: ComparisonOperator? = nil, comparisonValue: String? = nil) {
            self.comparisonOperator = comparisonOperator
            self.comparisonValue = comparisonValue
        }

        public func validate(name: String) throws {
            try self.validate(self.comparisonValue, name: "comparisonValue", parent: name, max: 256)
            try self.validate(self.comparisonValue, name: "comparisonValue", parent: name, min: 1)
            try self.validate(self.comparisonValue, name: "comparisonValue", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case comparisonOperator = "ComparisonOperator"
            case comparisonValue = "ComparisonValue"
        }
    }

    public struct CreateSignalingChannelInput: AWSEncodableShape {
        /// A name for the signaling channel that you are creating. It must be unique for each Amazon Web Services account and Amazon Web Services Region.
        public let channelName: String
        /// A type of the signaling channel that you are creating. Currently, SINGLE_MASTER is the only supported channel type.
        public let channelType: ChannelType?
        /// A structure containing the configuration for the SINGLE_MASTER channel type.
        public let singleMasterConfiguration: SingleMasterConfiguration?
        /// A set of tags (key-value pairs) that you want to associate with this channel.
        public let tags: [Tag]?

        @inlinable
        public init(channelName: String, channelType: ChannelType? = nil, singleMasterConfiguration: SingleMasterConfiguration? = nil, tags: [Tag]? = nil) {
            self.channelName = channelName
            self.channelType = channelType
            self.singleMasterConfiguration = singleMasterConfiguration
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.channelName, name: "channelName", parent: name, max: 256)
            try self.validate(self.channelName, name: "channelName", parent: name, min: 1)
            try self.validate(self.channelName, name: "channelName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.singleMasterConfiguration?.validate(name: "\(name).singleMasterConfiguration")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case channelName = "ChannelName"
            case channelType = "ChannelType"
            case singleMasterConfiguration = "SingleMasterConfiguration"
            case tags = "Tags"
        }
    }

    public struct CreateSignalingChannelOutput: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the created channel.
        public let channelARN: String?

        @inlinable
        public init(channelARN: String? = nil) {
            self.channelARN = channelARN
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
        }
    }

    public struct CreateStreamInput: AWSEncodableShape {
        /// The number of hours that you want to retain the data in the stream. Kinesis Video Streams retains the data in a data store that is associated with the stream. The default value is 0, indicating that the stream does not persist data. When the DataRetentionInHours value is 0, consumers can still consume the fragments that remain in the service host buffer, which has a retention time limit of 5 minutes and a retention memory limit of 200 MB. Fragments are removed from the buffer when either limit is reached.
        public let dataRetentionInHours: Int?
        /// The name of the device that is writing to the stream.   In the current implementation, Kinesis Video Streams does not use this name.
        public let deviceName: String?
        /// The ID of the Key Management Service (KMS) key that you want Kinesis Video Streams to use to encrypt stream data. If no key ID is specified, the default, Kinesis Video-managed key (Amazon Web Services/kinesisvideo) is used. For more information, see DescribeKey.
        public let kmsKeyId: String?
        /// The media type of the stream. Consumers of the stream can use this information when processing the stream. For more information about media types, see Media Types. If you choose to specify the MediaType, see Naming Requirements for guidelines. Example valid values include "video/h264" and "video/h264,audio/aac". This parameter is optional; the default value is null (or empty in JSON).
        public let mediaType: String?
        /// A name for the stream that you are creating. The stream name is an identifier for the stream, and must be unique for each account and region.
        public let streamName: String
        /// A list of tags to associate with the specified stream. Each tag is a key-value pair (the value is optional).
        public let tags: [String: String]?

        @inlinable
        public init(dataRetentionInHours: Int? = nil, deviceName: String? = nil, kmsKeyId: String? = nil, mediaType: String? = nil, streamName: String, tags: [String: String]? = nil) {
            self.dataRetentionInHours = dataRetentionInHours
            self.deviceName = deviceName
            self.kmsKeyId = kmsKeyId
            self.mediaType = mediaType
            self.streamName = streamName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.dataRetentionInHours, name: "dataRetentionInHours", parent: name, min: 0)
            try self.validate(self.deviceName, name: "deviceName", parent: name, max: 128)
            try self.validate(self.deviceName, name: "deviceName", parent: name, min: 1)
            try self.validate(self.deviceName, name: "deviceName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 2048)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, min: 1)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, pattern: "^.+$")
            try self.validate(self.mediaType, name: "mediaType", parent: name, max: 128)
            try self.validate(self.mediaType, name: "mediaType", parent: name, min: 1)
            try self.validate(self.mediaType, name: "mediaType", parent: name, pattern: "^[\\w\\-\\.\\+]+/[\\w\\-\\.\\+]+(,[\\w\\-\\.\\+]+/[\\w\\-\\.\\+]+)*$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*$")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case dataRetentionInHours = "DataRetentionInHours"
            case deviceName = "DeviceName"
            case kmsKeyId = "KmsKeyId"
            case mediaType = "MediaType"
            case streamName = "StreamName"
            case tags = "Tags"
        }
    }

    public struct CreateStreamOutput: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?

        @inlinable
        public init(streamARN: String? = nil) {
            self.streamARN = streamARN
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
        }
    }

    public struct DeleteEdgeConfigurationInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the stream. Specify either the StreamName or the StreamARN.
        public let streamARN: String?
        /// The name of the stream from which to delete the edge configuration. Specify either the StreamName or the StreamARN.
        public let streamName: String?

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil) {
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct DeleteEdgeConfigurationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteSignalingChannelInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the signaling channel that you want to delete.
        public let channelARN: String
        /// The current version of the signaling channel that you want to delete. You can obtain the current version by invoking the DescribeSignalingChannel or ListSignalingChannels API operations.
        public let currentVersion: String?

        @inlinable
        public init(channelARN: String, currentVersion: String? = nil) {
            self.channelARN = channelARN
            self.currentVersion = currentVersion
        }

        public func validate(name: String) throws {
            try self.validate(self.channelARN, name: "channelARN", parent: name, max: 1024)
            try self.validate(self.channelARN, name: "channelARN", parent: name, min: 1)
            try self.validate(self.channelARN, name: "channelARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, max: 64)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, min: 1)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, pattern: "^[a-zA-Z0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case currentVersion = "CurrentVersion"
        }
    }

    public struct DeleteSignalingChannelOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteStreamInput: AWSEncodableShape {
        /// Optional: The version of the stream that you want to delete.  Specify the version as a safeguard to ensure that your are deleting the correct stream. To get the stream version, use the DescribeStream API. If not specified, only the CreationTime is checked before deleting the stream.
        public let currentVersion: String?
        /// The Amazon Resource Name (ARN) of the stream that you want to delete.
        public let streamARN: String

        @inlinable
        public init(currentVersion: String? = nil, streamARN: String) {
            self.currentVersion = currentVersion
            self.streamARN = streamARN
        }

        public func validate(name: String) throws {
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, max: 64)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, min: 1)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, pattern: "^[a-zA-Z0-9]+$")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case currentVersion = "CurrentVersion"
            case streamARN = "StreamARN"
        }
    }

    public struct DeleteStreamOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeletionConfig: AWSEncodableShape & AWSDecodableShape {
        /// The boolean value used to indicate whether or not you want to mark the media for deletion, once it has been uploaded to  the Kinesis Video Stream cloud. The media files can be deleted if any of the deletion configuration values are  set to true, such as when the limit for the EdgeRetentionInHours, or the MaxLocalMediaSizeInMB, has been reached.   Since the default value is set to true, configure the uploader schedule such  that the media files are not being deleted before they are initially uploaded to the  Amazon Web Services cloud.
        public let deleteAfterUpload: Bool?
        /// The number of hours that you want to retain the data in the stream on the Edge Agent. The default value of the retention time is 720 hours, which translates to 30 days.
        public let edgeRetentionInHours: Int?
        /// The value of the local size required in order to delete the edge configuration.
        public let localSizeConfig: LocalSizeConfig?

        @inlinable
        public init(deleteAfterUpload: Bool? = nil, edgeRetentionInHours: Int? = nil, localSizeConfig: LocalSizeConfig? = nil) {
            self.deleteAfterUpload = deleteAfterUpload
            self.edgeRetentionInHours = edgeRetentionInHours
            self.localSizeConfig = localSizeConfig
        }

        public func validate(name: String) throws {
            try self.validate(self.edgeRetentionInHours, name: "edgeRetentionInHours", parent: name, max: 720)
            try self.validate(self.edgeRetentionInHours, name: "edgeRetentionInHours", parent: name, min: 1)
            try self.localSizeConfig?.validate(name: "\(name).localSizeConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case deleteAfterUpload = "DeleteAfterUpload"
            case edgeRetentionInHours = "EdgeRetentionInHours"
            case localSizeConfig = "LocalSizeConfig"
        }
    }

    public struct DescribeEdgeConfigurationInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the stream. Specify either the StreamNameor the StreamARN.
        public let streamARN: String?
        /// The name of the stream whose edge configuration you want to update. Specify either the StreamName or  the StreamARN.
        public let streamName: String?

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil) {
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct DescribeEdgeConfigurationOutput: AWSDecodableShape {
        /// The timestamp at which a stream’s edge configuration was first created.
        public let creationTime: Date?
        /// An object that contains the latest status details for an edge agent's recorder and uploader jobs. Use this information to determine the current health of an edge agent.
        public let edgeAgentStatus: EdgeAgentStatus?
        /// A description of the stream's edge configuration that will be used to sync  with the Edge Agent IoT Greengrass component. The Edge Agent component will run on an IoT Hub Device setup at your premise.
        public let edgeConfig: EdgeConfig?
        /// A description of the generated failure status.
        public let failedStatusDetails: String?
        /// The timestamp at which a stream’s edge configuration was last updated.
        public let lastUpdatedTime: Date?
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?
        /// The name of the stream from which the edge configuration was updated.
        public let streamName: String?
        /// The latest status of the edge configuration update.
        public let syncStatus: SyncStatus?

        @inlinable
        public init(creationTime: Date? = nil, edgeAgentStatus: EdgeAgentStatus? = nil, edgeConfig: EdgeConfig? = nil, failedStatusDetails: String? = nil, lastUpdatedTime: Date? = nil, streamARN: String? = nil, streamName: String? = nil, syncStatus: SyncStatus? = nil) {
            self.creationTime = creationTime
            self.edgeAgentStatus = edgeAgentStatus
            self.edgeConfig = edgeConfig
            self.failedStatusDetails = failedStatusDetails
            self.lastUpdatedTime = lastUpdatedTime
            self.streamARN = streamARN
            self.streamName = streamName
            self.syncStatus = syncStatus
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "CreationTime"
            case edgeAgentStatus = "EdgeAgentStatus"
            case edgeConfig = "EdgeConfig"
            case failedStatusDetails = "FailedStatusDetails"
            case lastUpdatedTime = "LastUpdatedTime"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
            case syncStatus = "SyncStatus"
        }
    }

    public struct DescribeImageGenerationConfigurationInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the Kinesis video stream from which to retrieve the image generation configuration. You must specify either the StreamName or the StreamARN.
        public let streamARN: String?
        /// The name of the stream from which to retrieve the image generation configuration. You must specify either the StreamName or the StreamARN.
        public let streamName: String?

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil) {
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct DescribeImageGenerationConfigurationOutput: AWSDecodableShape {
        /// The structure that contains the information required for the Kinesis video stream (KVS) images delivery. If this structure is null, the configuration will be deleted from the stream.
        public let imageGenerationConfiguration: ImageGenerationConfiguration?

        @inlinable
        public init(imageGenerationConfiguration: ImageGenerationConfiguration? = nil) {
            self.imageGenerationConfiguration = imageGenerationConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case imageGenerationConfiguration = "ImageGenerationConfiguration"
        }
    }

    public struct DescribeMappedResourceConfigurationInput: AWSEncodableShape {
        /// The maximum number of results to return in the response.
        public let maxResults: Int?
        /// The token to provide in your next request, to get another batch of results.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?
        /// The name of the stream.
        public let streamName: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, streamARN: String? = nil, streamName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=]*$")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct DescribeMappedResourceConfigurationOutput: AWSDecodableShape {
        /// A structure that encapsulates, or contains, the media storage configuration properties.
        public let mappedResourceConfigurationList: [MappedResourceConfigurationListItem]?
        /// The token that was used in the NextTokenrequest to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(mappedResourceConfigurationList: [MappedResourceConfigurationListItem]? = nil, nextToken: String? = nil) {
            self.mappedResourceConfigurationList = mappedResourceConfigurationList
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case mappedResourceConfigurationList = "MappedResourceConfigurationList"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeMediaStorageConfigurationInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the channel.
        public let channelARN: String?
        /// The name of the channel.
        public let channelName: String?

        @inlinable
        public init(channelARN: String? = nil, channelName: String? = nil) {
            self.channelARN = channelARN
            self.channelName = channelName
        }

        public func validate(name: String) throws {
            try self.validate(self.channelARN, name: "channelARN", parent: name, max: 1024)
            try self.validate(self.channelARN, name: "channelARN", parent: name, min: 1)
            try self.validate(self.channelARN, name: "channelARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.channelName, name: "channelName", parent: name, max: 256)
            try self.validate(self.channelName, name: "channelName", parent: name, min: 1)
            try self.validate(self.channelName, name: "channelName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case channelName = "ChannelName"
        }
    }

    public struct DescribeMediaStorageConfigurationOutput: AWSDecodableShape {
        /// A structure that encapsulates, or contains, the media storage configuration properties.
        public let mediaStorageConfiguration: MediaStorageConfiguration?

        @inlinable
        public init(mediaStorageConfiguration: MediaStorageConfiguration? = nil) {
            self.mediaStorageConfiguration = mediaStorageConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case mediaStorageConfiguration = "MediaStorageConfiguration"
        }
    }

    public struct DescribeNotificationConfigurationInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the Kinesis video stream from where you want to retrieve the notification configuration. You must specify either the StreamName or the StreamARN.
        public let streamARN: String?
        /// The name of the stream from which to retrieve the notification configuration. You must specify either the StreamName or the StreamARN.
        public let streamName: String?

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil) {
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct DescribeNotificationConfigurationOutput: AWSDecodableShape {
        /// The structure that contains the information required for notifications. If the structure is null, the configuration will be deleted from the stream.
        public let notificationConfiguration: NotificationConfiguration?

        @inlinable
        public init(notificationConfiguration: NotificationConfiguration? = nil) {
            self.notificationConfiguration = notificationConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case notificationConfiguration = "NotificationConfiguration"
        }
    }

    public struct DescribeSignalingChannelInput: AWSEncodableShape {
        /// The ARN of the signaling channel that you want to describe.
        public let channelARN: String?
        /// The name of the signaling channel that you want to describe.
        public let channelName: String?

        @inlinable
        public init(channelARN: String? = nil, channelName: String? = nil) {
            self.channelARN = channelARN
            self.channelName = channelName
        }

        public func validate(name: String) throws {
            try self.validate(self.channelARN, name: "channelARN", parent: name, max: 1024)
            try self.validate(self.channelARN, name: "channelARN", parent: name, min: 1)
            try self.validate(self.channelARN, name: "channelARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.channelName, name: "channelName", parent: name, max: 256)
            try self.validate(self.channelName, name: "channelName", parent: name, min: 1)
            try self.validate(self.channelName, name: "channelName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case channelName = "ChannelName"
        }
    }

    public struct DescribeSignalingChannelOutput: AWSDecodableShape {
        /// A structure that encapsulates the specified signaling channel's metadata and properties.
        public let channelInfo: ChannelInfo?

        @inlinable
        public init(channelInfo: ChannelInfo? = nil) {
            self.channelInfo = channelInfo
        }

        private enum CodingKeys: String, CodingKey {
            case channelInfo = "ChannelInfo"
        }
    }

    public struct DescribeStreamInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?
        /// The name of the stream.
        public let streamName: String?

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil) {
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct DescribeStreamOutput: AWSDecodableShape {
        /// An object that describes the stream.
        public let streamInfo: StreamInfo?

        @inlinable
        public init(streamInfo: StreamInfo? = nil) {
            self.streamInfo = streamInfo
        }

        private enum CodingKeys: String, CodingKey {
            case streamInfo = "StreamInfo"
        }
    }

    public struct EdgeAgentStatus: AWSDecodableShape {
        /// The latest status of a stream’s edge recording job.
        public let lastRecorderStatus: LastRecorderStatus?
        /// The latest status of a stream’s edge to cloud uploader job.
        public let lastUploaderStatus: LastUploaderStatus?

        @inlinable
        public init(lastRecorderStatus: LastRecorderStatus? = nil, lastUploaderStatus: LastUploaderStatus? = nil) {
            self.lastRecorderStatus = lastRecorderStatus
            self.lastUploaderStatus = lastUploaderStatus
        }

        private enum CodingKeys: String, CodingKey {
            case lastRecorderStatus = "LastRecorderStatus"
            case lastUploaderStatus = "LastUploaderStatus"
        }
    }

    public struct EdgeConfig: AWSEncodableShape & AWSDecodableShape {
        /// The deletion configuration is made up of the retention time (EdgeRetentionInHours) and local size configuration (LocalSizeConfig) details that are used to make the deletion.
        public let deletionConfig: DeletionConfig?
        /// The "Internet of Things (IoT) Thing" Arn of the stream.
        public let hubDeviceArn: String
        /// The recorder configuration consists of the local MediaSourceConfig details, that are used as  credentials to access the local media files streamed on the camera.
        public let recorderConfig: RecorderConfig
        /// The uploader configuration contains the ScheduleExpression details that are used to schedule upload jobs for the recorded media files from the Edge Agent to a Kinesis Video Stream.
        public let uploaderConfig: UploaderConfig?

        @inlinable
        public init(deletionConfig: DeletionConfig? = nil, hubDeviceArn: String, recorderConfig: RecorderConfig, uploaderConfig: UploaderConfig? = nil) {
            self.deletionConfig = deletionConfig
            self.hubDeviceArn = hubDeviceArn
            self.recorderConfig = recorderConfig
            self.uploaderConfig = uploaderConfig
        }

        public func validate(name: String) throws {
            try self.deletionConfig?.validate(name: "\(name).deletionConfig")
            try self.validate(self.hubDeviceArn, name: "hubDeviceArn", parent: name, max: 1024)
            try self.validate(self.hubDeviceArn, name: "hubDeviceArn", parent: name, min: 1)
            try self.validate(self.hubDeviceArn, name: "hubDeviceArn", parent: name, pattern: "^arn:[a-z\\d-]+:iot:[a-z0-9-]+:[0-9]+:thing/[a-zA-Z0-9_.-]+$")
            try self.recorderConfig.validate(name: "\(name).recorderConfig")
            try self.uploaderConfig?.validate(name: "\(name).uploaderConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case deletionConfig = "DeletionConfig"
            case hubDeviceArn = "HubDeviceArn"
            case recorderConfig = "RecorderConfig"
            case uploaderConfig = "UploaderConfig"
        }
    }

    public struct GetDataEndpointInput: AWSEncodableShape {
        /// The name of the API action for which to get an endpoint.
        public let apiName: APIName
        /// The Amazon Resource Name (ARN) of the stream that you want to get the endpoint for. You must specify either this parameter or a StreamName in the request.
        public let streamARN: String?
        /// The name of the stream that you want to get the endpoint for. You must specify either this parameter or a StreamARN in the request.
        public let streamName: String?

        @inlinable
        public init(apiName: APIName, streamARN: String? = nil, streamName: String? = nil) {
            self.apiName = apiName
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case apiName = "APIName"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct GetDataEndpointOutput: AWSDecodableShape {
        /// The endpoint value. To read data from the stream or to write data to it, specify this endpoint in your application.
        public let dataEndpoint: String?

        @inlinable
        public init(dataEndpoint: String? = nil) {
            self.dataEndpoint = dataEndpoint
        }

        private enum CodingKeys: String, CodingKey {
            case dataEndpoint = "DataEndpoint"
        }
    }

    public struct GetSignalingChannelEndpointInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the signalling channel for which you want to get an endpoint.
        public let channelARN: String
        /// A structure containing the endpoint configuration for the SINGLE_MASTER channel type.
        public let singleMasterChannelEndpointConfiguration: SingleMasterChannelEndpointConfiguration?

        @inlinable
        public init(channelARN: String, singleMasterChannelEndpointConfiguration: SingleMasterChannelEndpointConfiguration? = nil) {
            self.channelARN = channelARN
            self.singleMasterChannelEndpointConfiguration = singleMasterChannelEndpointConfiguration
        }

        public func validate(name: String) throws {
            try self.validate(self.channelARN, name: "channelARN", parent: name, max: 1024)
            try self.validate(self.channelARN, name: "channelARN", parent: name, min: 1)
            try self.validate(self.channelARN, name: "channelARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.singleMasterChannelEndpointConfiguration?.validate(name: "\(name).singleMasterChannelEndpointConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case singleMasterChannelEndpointConfiguration = "SingleMasterChannelEndpointConfiguration"
        }
    }

    public struct GetSignalingChannelEndpointOutput: AWSDecodableShape {
        /// A list of endpoints for the specified signaling channel.
        public let resourceEndpointList: [ResourceEndpointListItem]?

        @inlinable
        public init(resourceEndpointList: [ResourceEndpointListItem]? = nil) {
            self.resourceEndpointList = resourceEndpointList
        }

        private enum CodingKeys: String, CodingKey {
            case resourceEndpointList = "ResourceEndpointList"
        }
    }

    public struct ImageGenerationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The structure that contains the information required to deliver images to a customer.
        public let destinationConfig: ImageGenerationDestinationConfig
        /// The accepted image format.
        public let format: Format
        /// The list of a key-value pair structure that contains extra parameters that can be applied when the image is generated. The FormatConfig key is the JPEGQuality, which indicates the JPEG quality key to be used to generate the image.  The FormatConfig value accepts ints from 1 to 100. If the value is 1, the image will be generated with less quality and the best compression.  If the value is 100, the image will be generated with the best quality and less compression. If no value is provided, the default value of the JPEGQuality key will be set to 80.
        public let formatConfig: [FormatConfigKey: String]?
        /// The height of the output image that is used in conjunction with the WidthPixels parameter. When both HeightPixels and WidthPixels parameters are provided, the image will be stretched to fit the specified aspect ratio.  If only the HeightPixels parameter is provided, its original aspect ratio will be used to calculate the WidthPixels ratio. If neither parameter is provided, the original image size will be returned.
        public let heightPixels: Int?
        /// The origin of the Server or Producer timestamps to use to generate the images.
        public let imageSelectorType: ImageSelectorType
        /// The time interval in milliseconds (ms) at which the images need to be generated from the stream. The minimum value that can be provided is 200 ms. If the timestamp range is less than the sampling interval, the  Image from the StartTimestamp will be returned if available.
        public let samplingInterval: Int
        /// Indicates whether the ContinuousImageGenerationConfigurations API is enabled or disabled.
        public let status: ConfigurationStatus
        /// The width of the output image that is used in conjunction with the HeightPixels parameter. When both WidthPixels and  HeightPixels parameters are provided, the image will be stretched to fit the specified aspect ratio. If only the WidthPixels parameter is  provided, its original aspect ratio will be used to calculate the HeightPixels ratio. If neither parameter is provided, the original image size will be returned.
        public let widthPixels: Int?

        @inlinable
        public init(destinationConfig: ImageGenerationDestinationConfig, format: Format, formatConfig: [FormatConfigKey: String]? = nil, heightPixels: Int? = nil, imageSelectorType: ImageSelectorType, samplingInterval: Int, status: ConfigurationStatus, widthPixels: Int? = nil) {
            self.destinationConfig = destinationConfig
            self.format = format
            self.formatConfig = formatConfig
            self.heightPixels = heightPixels
            self.imageSelectorType = imageSelectorType
            self.samplingInterval = samplingInterval
            self.status = status
            self.widthPixels = widthPixels
        }

        public func validate(name: String) throws {
            try self.destinationConfig.validate(name: "\(name).destinationConfig")
            try self.formatConfig?.forEach {
                try validate($0.value, name: "formatConfig[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "formatConfig[\"\($0.key)\"]", parent: name, pattern: "^[a-zA-Z_0-9]+$")
            }
            try self.validate(self.formatConfig, name: "formatConfig", parent: name, max: 1)
            try self.validate(self.formatConfig, name: "formatConfig", parent: name, min: 1)
            try self.validate(self.heightPixels, name: "heightPixels", parent: name, max: 2160)
            try self.validate(self.heightPixels, name: "heightPixels", parent: name, min: 1)
            try self.validate(self.widthPixels, name: "widthPixels", parent: name, max: 3840)
            try self.validate(self.widthPixels, name: "widthPixels", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case destinationConfig = "DestinationConfig"
            case format = "Format"
            case formatConfig = "FormatConfig"
            case heightPixels = "HeightPixels"
            case imageSelectorType = "ImageSelectorType"
            case samplingInterval = "SamplingInterval"
            case status = "Status"
            case widthPixels = "WidthPixels"
        }
    }

    public struct ImageGenerationDestinationConfig: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Web Services Region of the S3 bucket where images will be delivered. This DestinationRegion must match the Region where the stream is located.
        public let destinationRegion: String
        /// The Uniform Resource Identifier (URI) that identifies where the images will be delivered.
        public let uri: String

        @inlinable
        public init(destinationRegion: String, uri: String) {
            self.destinationRegion = destinationRegion
            self.uri = uri
        }

        public func validate(name: String) throws {
            try self.validate(self.destinationRegion, name: "destinationRegion", parent: name, max: 14)
            try self.validate(self.destinationRegion, name: "destinationRegion", parent: name, min: 9)
            try self.validate(self.destinationRegion, name: "destinationRegion", parent: name, pattern: "^[a-z]+(-[a-z]+)?-[a-z]+-[0-9]$")
            try self.validate(self.uri, name: "uri", parent: name, max: 255)
            try self.validate(self.uri, name: "uri", parent: name, min: 1)
            try self.validate(self.uri, name: "uri", parent: name, pattern: "^[a-zA-Z_0-9]+:(//)?([^/]+)/?([^*]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case destinationRegion = "DestinationRegion"
            case uri = "Uri"
        }
    }

    public struct LastRecorderStatus: AWSDecodableShape {
        /// A description of a recorder job’s latest status.
        public let jobStatusDetails: String?
        /// The timestamp at which the recorder job was last executed and media stored to local disk.
        public let lastCollectedTime: Date?
        /// The timestamp at which the recorder status was last updated.
        public let lastUpdatedTime: Date?
        /// The status of the latest recorder job.
        public let recorderStatus: RecorderStatus?

        @inlinable
        public init(jobStatusDetails: String? = nil, lastCollectedTime: Date? = nil, lastUpdatedTime: Date? = nil, recorderStatus: RecorderStatus? = nil) {
            self.jobStatusDetails = jobStatusDetails
            self.lastCollectedTime = lastCollectedTime
            self.lastUpdatedTime = lastUpdatedTime
            self.recorderStatus = recorderStatus
        }

        private enum CodingKeys: String, CodingKey {
            case jobStatusDetails = "JobStatusDetails"
            case lastCollectedTime = "LastCollectedTime"
            case lastUpdatedTime = "LastUpdatedTime"
            case recorderStatus = "RecorderStatus"
        }
    }

    public struct LastUploaderStatus: AWSDecodableShape {
        /// A description of an uploader job’s latest status.
        public let jobStatusDetails: String?
        /// The timestamp at which the uploader job was last executed and media collected to the cloud.
        public let lastCollectedTime: Date?
        /// The timestamp at which the uploader status was last updated.
        public let lastUpdatedTime: Date?
        /// The status of the latest uploader job.
        public let uploaderStatus: UploaderStatus?

        @inlinable
        public init(jobStatusDetails: String? = nil, lastCollectedTime: Date? = nil, lastUpdatedTime: Date? = nil, uploaderStatus: UploaderStatus? = nil) {
            self.jobStatusDetails = jobStatusDetails
            self.lastCollectedTime = lastCollectedTime
            self.lastUpdatedTime = lastUpdatedTime
            self.uploaderStatus = uploaderStatus
        }

        private enum CodingKeys: String, CodingKey {
            case jobStatusDetails = "JobStatusDetails"
            case lastCollectedTime = "LastCollectedTime"
            case lastUpdatedTime = "LastUpdatedTime"
            case uploaderStatus = "UploaderStatus"
        }
    }

    public struct ListEdgeAgentConfigurationsEdgeConfig: AWSDecodableShape {
        /// The timestamp when the stream first created the edge config.
        public let creationTime: Date?
        public let edgeConfig: EdgeConfig?
        /// A description of the generated failure status.
        public let failedStatusDetails: String?
        /// The timestamp when the stream last updated the edge config.
        public let lastUpdatedTime: Date?
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?
        /// The name of the stream.
        public let streamName: String?
        /// The current sync status of the stream's edge configuration.
        public let syncStatus: SyncStatus?

        @inlinable
        public init(creationTime: Date? = nil, edgeConfig: EdgeConfig? = nil, failedStatusDetails: String? = nil, lastUpdatedTime: Date? = nil, streamARN: String? = nil, streamName: String? = nil, syncStatus: SyncStatus? = nil) {
            self.creationTime = creationTime
            self.edgeConfig = edgeConfig
            self.failedStatusDetails = failedStatusDetails
            self.lastUpdatedTime = lastUpdatedTime
            self.streamARN = streamARN
            self.streamName = streamName
            self.syncStatus = syncStatus
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "CreationTime"
            case edgeConfig = "EdgeConfig"
            case failedStatusDetails = "FailedStatusDetails"
            case lastUpdatedTime = "LastUpdatedTime"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
            case syncStatus = "SyncStatus"
        }
    }

    public struct ListEdgeAgentConfigurationsInput: AWSEncodableShape {
        /// The "Internet of Things (IoT) Thing" Arn of the edge agent.
        public let hubDeviceArn: String
        /// The maximum number of edge configurations to return in the response. The default is 5.
        public let maxResults: Int?
        /// If you specify this parameter, when the result of a ListEdgeAgentConfigurations operation is truncated, the call returns the NextToken in the response. To get another batch of edge configurations, provide this token in your next request.
        public let nextToken: String?

        @inlinable
        public init(hubDeviceArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.hubDeviceArn = hubDeviceArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.hubDeviceArn, name: "hubDeviceArn", parent: name, max: 1024)
            try self.validate(self.hubDeviceArn, name: "hubDeviceArn", parent: name, min: 1)
            try self.validate(self.hubDeviceArn, name: "hubDeviceArn", parent: name, pattern: "^arn:[a-z\\d-]+:iot:[a-z0-9-]+:[0-9]+:thing/[a-zA-Z0-9_.-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 10)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case hubDeviceArn = "HubDeviceArn"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListEdgeAgentConfigurationsOutput: AWSDecodableShape {
        /// A description of a single stream's edge configuration.
        public let edgeConfigs: [ListEdgeAgentConfigurationsEdgeConfig]?
        /// If the response is truncated, the call returns this element with a given token. To get the next batch of edge configurations, use this token in your next request.
        public let nextToken: String?

        @inlinable
        public init(edgeConfigs: [ListEdgeAgentConfigurationsEdgeConfig]? = nil, nextToken: String? = nil) {
            self.edgeConfigs = edgeConfigs
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case edgeConfigs = "EdgeConfigs"
            case nextToken = "NextToken"
        }
    }

    public struct ListSignalingChannelsInput: AWSEncodableShape {
        /// Optional: Returns only the channels that satisfy a specific condition.
        public let channelNameCondition: ChannelNameCondition?
        /// The maximum number of channels to return in the response. The default is 500.
        public let maxResults: Int?
        /// If you specify this parameter, when the result of a ListSignalingChannels operation is truncated, the call returns the NextToken in the response. To get another batch of channels, provide this token in your next request.
        public let nextToken: String?

        @inlinable
        public init(channelNameCondition: ChannelNameCondition? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.channelNameCondition = channelNameCondition
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.channelNameCondition?.validate(name: "\(name).channelNameCondition")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 10000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case channelNameCondition = "ChannelNameCondition"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListSignalingChannelsOutput: AWSDecodableShape {
        /// An array of ChannelInfo objects.
        public let channelInfoList: [ChannelInfo]?
        /// If the response is truncated, the call returns this element with a token. To get the next batch of streams, use this token in your next request.
        public let nextToken: String?

        @inlinable
        public init(channelInfoList: [ChannelInfo]? = nil, nextToken: String? = nil) {
            self.channelInfoList = channelInfoList
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case channelInfoList = "ChannelInfoList"
            case nextToken = "NextToken"
        }
    }

    public struct ListStreamsInput: AWSEncodableShape {
        /// The maximum number of streams to return in the response. The default is 10,000.
        public let maxResults: Int?
        /// If you specify this parameter, when the result of a ListStreams operation is truncated, the call returns the NextToken in the response. To get another batch of streams, provide this token in your next request.
        public let nextToken: String?
        /// Optional: Returns only streams that satisfy a specific condition. Currently, you can specify only the prefix of a stream name as a condition.
        public let streamNameCondition: StreamNameCondition?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, streamNameCondition: StreamNameCondition? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.streamNameCondition = streamNameCondition
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 10000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=]*$")
            try self.streamNameCondition?.validate(name: "\(name).streamNameCondition")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case streamNameCondition = "StreamNameCondition"
        }
    }

    public struct ListStreamsOutput: AWSDecodableShape {
        /// If the response is truncated, the call returns this element with a token. To get the next batch of streams, use this token in your next request.
        public let nextToken: String?
        /// An array of StreamInfo objects.
        public let streamInfoList: [StreamInfo]?

        @inlinable
        public init(nextToken: String? = nil, streamInfoList: [StreamInfo]? = nil) {
            self.nextToken = nextToken
            self.streamInfoList = streamInfoList
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case streamInfoList = "StreamInfoList"
        }
    }

    public struct ListTagsForResourceInput: AWSEncodableShape {
        /// If you specify this parameter and the result of a ListTagsForResource call is truncated, the response includes a token that you can use in the next request to fetch the next batch of tags.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the signaling channel for which you want to list tags.
        public let resourceARN: String

        @inlinable
        public init(nextToken: String? = nil, resourceARN: String) {
            self.nextToken = nextToken
            self.resourceARN = resourceARN
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=]*$")
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1024)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case resourceARN = "ResourceARN"
        }
    }

    public struct ListTagsForResourceOutput: AWSDecodableShape {
        /// If you specify this parameter and the result of a ListTagsForResource call is truncated, the response includes a token that you can use in the next request to fetch the next set of tags.
        public let nextToken: String?
        /// A map of tag keys and values associated with the specified signaling channel.
        public let tags: [String: String]?

        @inlinable
        public init(nextToken: String? = nil, tags: [String: String]? = nil) {
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct ListTagsForStreamInput: AWSEncodableShape {
        /// If you specify this parameter and the result of a ListTagsForStream call is truncated, the response includes a token that you can use in the next request to fetch the next batch of tags.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the stream that you want to list tags for.
        public let streamARN: String?
        /// The name of the stream that you want to list tags for.
        public let streamName: String?

        @inlinable
        public init(nextToken: String? = nil, streamARN: String? = nil, streamName: String? = nil) {
            self.nextToken = nextToken
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/=]*$")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct ListTagsForStreamOutput: AWSDecodableShape {
        /// If you specify this parameter and the result of a ListTags call is truncated, the response includes a token that you can use in the next request to fetch the next set of tags.
        public let nextToken: String?
        /// A map of tag keys and values associated with the specified stream.
        public let tags: [String: String]?

        @inlinable
        public init(nextToken: String? = nil, tags: [String: String]? = nil) {
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct LocalSizeConfig: AWSEncodableShape & AWSDecodableShape {
        /// The overall maximum size of the media that you want to store for a stream on the Edge Agent.
        public let maxLocalMediaSizeInMB: Int?
        /// The strategy to perform when a stream’s MaxLocalMediaSizeInMB limit is reached.
        public let strategyOnFullSize: StrategyOnFullSize?

        @inlinable
        public init(maxLocalMediaSizeInMB: Int? = nil, strategyOnFullSize: StrategyOnFullSize? = nil) {
            self.maxLocalMediaSizeInMB = maxLocalMediaSizeInMB
            self.strategyOnFullSize = strategyOnFullSize
        }

        public func validate(name: String) throws {
            try self.validate(self.maxLocalMediaSizeInMB, name: "maxLocalMediaSizeInMB", parent: name, max: 2000000)
            try self.validate(self.maxLocalMediaSizeInMB, name: "maxLocalMediaSizeInMB", parent: name, min: 64)
        }

        private enum CodingKeys: String, CodingKey {
            case maxLocalMediaSizeInMB = "MaxLocalMediaSizeInMB"
            case strategyOnFullSize = "StrategyOnFullSize"
        }
    }

    public struct MappedResourceConfigurationListItem: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the Kinesis Video Stream resource, associated with the stream.
        public let arn: String?
        /// The type of the associated resource for the kinesis video stream.
        public let type: String?

        @inlinable
        public init(arn: String? = nil, type: String? = nil) {
            self.arn = arn
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case type = "Type"
        }
    }

    public struct MediaSourceConfig: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Web Services Secrets Manager ARN for the username and password of the camera, or a local media file location.
        public let mediaUriSecretArn: String
        /// The Uniform Resource Identifier (URI) type. The FILE_URI value can be used to stream  local media files.  Preview only supports the RTSP_URI media source URI format .
        public let mediaUriType: MediaUriType

        @inlinable
        public init(mediaUriSecretArn: String, mediaUriType: MediaUriType) {
            self.mediaUriSecretArn = mediaUriSecretArn
            self.mediaUriType = mediaUriType
        }

        public func validate(name: String) throws {
            try self.validate(self.mediaUriSecretArn, name: "mediaUriSecretArn", parent: name, max: 2048)
            try self.validate(self.mediaUriSecretArn, name: "mediaUriSecretArn", parent: name, min: 20)
            try self.validate(self.mediaUriSecretArn, name: "mediaUriSecretArn", parent: name, pattern: "^arn:[a-z\\d-]+:secretsmanager:[a-z0-9-]+:[0-9]+:secret:[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case mediaUriSecretArn = "MediaUriSecretArn"
            case mediaUriType = "MediaUriType"
        }
    }

    public struct MediaStorageConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The status of the media storage configuration.
        public let status: MediaStorageConfigurationStatus
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?

        @inlinable
        public init(status: MediaStorageConfigurationStatus, streamARN: String? = nil) {
            self.status = status
            self.streamARN = streamARN
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case status = "Status"
            case streamARN = "StreamARN"
        }
    }

    public struct NotificationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The destination information required to deliver a notification to a customer.
        public let destinationConfig: NotificationDestinationConfig
        /// Indicates if a notification configuration is enabled or disabled.
        public let status: ConfigurationStatus

        @inlinable
        public init(destinationConfig: NotificationDestinationConfig, status: ConfigurationStatus) {
            self.destinationConfig = destinationConfig
            self.status = status
        }

        public func validate(name: String) throws {
            try self.destinationConfig.validate(name: "\(name).destinationConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case destinationConfig = "DestinationConfig"
            case status = "Status"
        }
    }

    public struct NotificationDestinationConfig: AWSEncodableShape & AWSDecodableShape {
        /// The Uniform Resource Identifier (URI) that identifies where the images will be delivered.
        public let uri: String

        @inlinable
        public init(uri: String) {
            self.uri = uri
        }

        public func validate(name: String) throws {
            try self.validate(self.uri, name: "uri", parent: name, max: 255)
            try self.validate(self.uri, name: "uri", parent: name, min: 1)
            try self.validate(self.uri, name: "uri", parent: name, pattern: "^[a-zA-Z_0-9]+:(//)?([^/]+)/?([^*]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case uri = "Uri"
        }
    }

    public struct RecorderConfig: AWSEncodableShape & AWSDecodableShape {
        /// The configuration details that consist of the credentials required  (MediaUriSecretArn and MediaUriType) to access the media files  streamed to the camera.
        public let mediaSourceConfig: MediaSourceConfig
        /// The configuration that consists of the ScheduleExpression and the  DurationInMinutes details that specify the scheduling to record from a camera, or local media file, onto the Edge Agent. If the ScheduleExpression attribute is not provided, then the Edge Agent will always be set to recording mode.
        public let scheduleConfig: ScheduleConfig?

        @inlinable
        public init(mediaSourceConfig: MediaSourceConfig, scheduleConfig: ScheduleConfig? = nil) {
            self.mediaSourceConfig = mediaSourceConfig
            self.scheduleConfig = scheduleConfig
        }

        public func validate(name: String) throws {
            try self.mediaSourceConfig.validate(name: "\(name).mediaSourceConfig")
            try self.scheduleConfig?.validate(name: "\(name).scheduleConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case mediaSourceConfig = "MediaSourceConfig"
            case scheduleConfig = "ScheduleConfig"
        }
    }

    public struct ResourceEndpointListItem: AWSDecodableShape {
        /// The protocol of the signaling channel returned by the GetSignalingChannelEndpoint API.
        public let `protocol`: ChannelProtocol?
        /// The endpoint of the signaling channel returned by the GetSignalingChannelEndpoint API.
        public let resourceEndpoint: String?

        @inlinable
        public init(protocol: ChannelProtocol? = nil, resourceEndpoint: String? = nil) {
            self.`protocol` = `protocol`
            self.resourceEndpoint = resourceEndpoint
        }

        private enum CodingKeys: String, CodingKey {
            case `protocol` = "Protocol"
            case resourceEndpoint = "ResourceEndpoint"
        }
    }

    public struct ScheduleConfig: AWSEncodableShape & AWSDecodableShape {
        /// The total duration to record the media. If the ScheduleExpression attribute is provided, then the DurationInSeconds attribute should also be specified.
        public let durationInSeconds: Int
        /// The Quartz cron expression that takes care of scheduling jobs to record from the camera, or local media file, onto the Edge Agent. If the ScheduleExpression is not provided for the RecorderConfig, then the Edge Agent will always be set to recording mode. For more information about Quartz, refer to the   Cron Trigger Tutorial page to understand the valid expressions and its use.
        public let scheduleExpression: String

        @inlinable
        public init(durationInSeconds: Int, scheduleExpression: String) {
            self.durationInSeconds = durationInSeconds
            self.scheduleExpression = scheduleExpression
        }

        public func validate(name: String) throws {
            try self.validate(self.durationInSeconds, name: "durationInSeconds", parent: name, max: 3600)
            try self.validate(self.durationInSeconds, name: "durationInSeconds", parent: name, min: 60)
            try self.validate(self.scheduleExpression, name: "scheduleExpression", parent: name, max: 100)
            try self.validate(self.scheduleExpression, name: "scheduleExpression", parent: name, min: 11)
            try self.validate(self.scheduleExpression, name: "scheduleExpression", parent: name, pattern: "^[^\\n]{11,100}$")
        }

        private enum CodingKeys: String, CodingKey {
            case durationInSeconds = "DurationInSeconds"
            case scheduleExpression = "ScheduleExpression"
        }
    }

    public struct SingleMasterChannelEndpointConfiguration: AWSEncodableShape {
        /// This property is used to determine the nature of communication over this SINGLE_MASTER signaling channel. If WSS is specified, this API returns a websocket endpoint. If HTTPS is specified, this API returns an HTTPS endpoint.
        public let protocols: [ChannelProtocol]?
        /// This property is used to determine messaging permissions in this SINGLE_MASTER signaling channel. If MASTER is specified, this API returns an endpoint that a client can use to receive offers from and send answers to any of the viewers on this signaling channel. If VIEWER is specified, this API returns an endpoint that a client can use only to send offers to another MASTER client on this signaling channel.
        public let role: ChannelRole?

        @inlinable
        public init(protocols: [ChannelProtocol]? = nil, role: ChannelRole? = nil) {
            self.protocols = protocols
            self.role = role
        }

        public func validate(name: String) throws {
            try self.validate(self.protocols, name: "protocols", parent: name, max: 5)
            try self.validate(self.protocols, name: "protocols", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case protocols = "Protocols"
            case role = "Role"
        }
    }

    public struct SingleMasterConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The period of time a signaling channel retains undelivered messages before they are discarded.
        public let messageTtlSeconds: Int?

        @inlinable
        public init(messageTtlSeconds: Int? = nil) {
            self.messageTtlSeconds = messageTtlSeconds
        }

        public func validate(name: String) throws {
            try self.validate(self.messageTtlSeconds, name: "messageTtlSeconds", parent: name, max: 120)
            try self.validate(self.messageTtlSeconds, name: "messageTtlSeconds", parent: name, min: 5)
        }

        private enum CodingKeys: String, CodingKey {
            case messageTtlSeconds = "MessageTtlSeconds"
        }
    }

    public struct StartEdgeConfigurationUpdateInput: AWSEncodableShape {
        /// The edge configuration details required to invoke the update process.
        public let edgeConfig: EdgeConfig
        ///  The Amazon Resource Name (ARN) of the stream. Specify either the  StreamName or the StreamARN.
        public let streamARN: String?
        /// The name of the stream whose edge configuration you want to update. Specify either the StreamName or the StreamARN.
        public let streamName: String?

        @inlinable
        public init(edgeConfig: EdgeConfig, streamARN: String? = nil, streamName: String? = nil) {
            self.edgeConfig = edgeConfig
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.edgeConfig.validate(name: "\(name).edgeConfig")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case edgeConfig = "EdgeConfig"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct StartEdgeConfigurationUpdateOutput: AWSDecodableShape {
        /// The timestamp at which a stream’s edge configuration was first created.
        public let creationTime: Date?
        /// A description of the stream's edge configuration that will be used to sync  with the Edge Agent IoT Greengrass component. The Edge Agent component will run on an IoT Hub Device setup at your premise.
        public let edgeConfig: EdgeConfig?
        /// A description of the generated failure status.
        public let failedStatusDetails: String?
        /// The timestamp at which a stream’s edge configuration was last updated.
        public let lastUpdatedTime: Date?
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?
        /// The name of the stream from which the edge configuration was updated.
        public let streamName: String?
        ///  The current sync status of the stream's edge configuration. When you invoke this API, the sync status will be set to the SYNCING state. Use the DescribeEdgeConfiguration API to get the latest status of the edge configuration.
        public let syncStatus: SyncStatus?

        @inlinable
        public init(creationTime: Date? = nil, edgeConfig: EdgeConfig? = nil, failedStatusDetails: String? = nil, lastUpdatedTime: Date? = nil, streamARN: String? = nil, streamName: String? = nil, syncStatus: SyncStatus? = nil) {
            self.creationTime = creationTime
            self.edgeConfig = edgeConfig
            self.failedStatusDetails = failedStatusDetails
            self.lastUpdatedTime = lastUpdatedTime
            self.streamARN = streamARN
            self.streamName = streamName
            self.syncStatus = syncStatus
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "CreationTime"
            case edgeConfig = "EdgeConfig"
            case failedStatusDetails = "FailedStatusDetails"
            case lastUpdatedTime = "LastUpdatedTime"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
            case syncStatus = "SyncStatus"
        }
    }

    public struct StreamInfo: AWSDecodableShape {
        /// A time stamp that indicates when the stream was created.
        public let creationTime: Date?
        /// How long the stream retains data, in hours.
        public let dataRetentionInHours: Int?
        /// The name of the device that is associated with the stream.
        public let deviceName: String?
        /// The ID of the Key Management Service (KMS) key that Kinesis Video Streams uses to encrypt data on the stream.
        public let kmsKeyId: String?
        /// The MediaType of the stream.
        public let mediaType: String?
        /// The status of the stream.
        public let status: Status?
        /// The Amazon Resource Name (ARN) of the stream.
        public let streamARN: String?
        /// The name of the stream.
        public let streamName: String?
        /// The version of the stream.
        public let version: String?

        @inlinable
        public init(creationTime: Date? = nil, dataRetentionInHours: Int? = nil, deviceName: String? = nil, kmsKeyId: String? = nil, mediaType: String? = nil, status: Status? = nil, streamARN: String? = nil, streamName: String? = nil, version: String? = nil) {
            self.creationTime = creationTime
            self.dataRetentionInHours = dataRetentionInHours
            self.deviceName = deviceName
            self.kmsKeyId = kmsKeyId
            self.mediaType = mediaType
            self.status = status
            self.streamARN = streamARN
            self.streamName = streamName
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "CreationTime"
            case dataRetentionInHours = "DataRetentionInHours"
            case deviceName = "DeviceName"
            case kmsKeyId = "KmsKeyId"
            case mediaType = "MediaType"
            case status = "Status"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
            case version = "Version"
        }
    }

    public struct StreamNameCondition: AWSEncodableShape {
        /// A comparison operator. Currently, you can specify only the BEGINS_WITH operator, which finds streams whose names start with a given prefix.
        public let comparisonOperator: ComparisonOperator?
        /// A value to compare.
        public let comparisonValue: String?

        @inlinable
        public init(comparisonOperator: ComparisonOperator? = nil, comparisonValue: String? = nil) {
            self.comparisonOperator = comparisonOperator
            self.comparisonValue = comparisonValue
        }

        public func validate(name: String) throws {
            try self.validate(self.comparisonValue, name: "comparisonValue", parent: name, max: 256)
            try self.validate(self.comparisonValue, name: "comparisonValue", parent: name, min: 1)
            try self.validate(self.comparisonValue, name: "comparisonValue", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case comparisonOperator = "ComparisonOperator"
            case comparisonValue = "ComparisonValue"
        }
    }

    public struct Tag: AWSEncodableShape {
        /// The key of the tag that is associated with the specified signaling channel.
        public let key: String
        /// The value of the tag that is associated with the specified signaling channel.
        public let value: String

        @inlinable
        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the signaling channel to which you want to add tags.
        public let resourceARN: String
        /// A list of tags to associate with the specified signaling channel. Each tag is a key-value pair.
        public let tags: [Tag]

        @inlinable
        public init(resourceARN: String, tags: [Tag]) {
            self.resourceARN = resourceARN
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1024)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tags = "Tags"
        }
    }

    public struct TagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct TagStreamInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource that you want to add the tag or tags to.
        public let streamARN: String?
        /// The name of the stream that you want to add the tag or tags to.
        public let streamName: String?
        /// A list of tags to associate with the specified stream. Each tag is a key-value pair (the value is optional).
        public let tags: [String: String]

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil, tags: [String: String]) {
            self.streamARN = streamARN
            self.streamName = streamName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*$")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
            case tags = "Tags"
        }
    }

    public struct TagStreamOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the signaling channel from which you want to remove tags.
        public let resourceARN: String
        /// A list of the keys of the tags that you want to remove.
        public let tagKeyList: [String]

        @inlinable
        public init(resourceARN: String, tagKeyList: [String]) {
            self.resourceARN = resourceARN
            self.tagKeyList = tagKeyList
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1024)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.tagKeyList.forEach {
                try validate($0, name: "tagKeyList[]", parent: name, max: 128)
                try validate($0, name: "tagKeyList[]", parent: name, min: 1)
                try validate($0, name: "tagKeyList[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tagKeyList, name: "tagKeyList", parent: name, max: 50)
            try self.validate(self.tagKeyList, name: "tagKeyList", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tagKeyList = "TagKeyList"
        }
    }

    public struct UntagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UntagStreamInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the stream that you want to remove tags from.
        public let streamARN: String?
        /// The name of the stream that you want to remove tags from.
        public let streamName: String?
        /// A list of the keys of the tags that you want to remove.
        public let tagKeyList: [String]

        @inlinable
        public init(streamARN: String? = nil, streamName: String? = nil, tagKeyList: [String]) {
            self.streamARN = streamARN
            self.streamName = streamName
            self.tagKeyList = tagKeyList
        }

        public func validate(name: String) throws {
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.tagKeyList.forEach {
                try validate($0, name: "tagKeyList[]", parent: name, max: 128)
                try validate($0, name: "tagKeyList[]", parent: name, min: 1)
                try validate($0, name: "tagKeyList[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tagKeyList, name: "tagKeyList", parent: name, max: 50)
            try self.validate(self.tagKeyList, name: "tagKeyList", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case streamARN = "StreamARN"
            case streamName = "StreamName"
            case tagKeyList = "TagKeyList"
        }
    }

    public struct UntagStreamOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateDataRetentionInput: AWSEncodableShape {
        /// The version of the stream whose retention period you want to change. To get the version, call either the DescribeStream or the ListStreams API.
        public let currentVersion: String
        /// The number of hours to adjust the current retention by. The value you specify is added to or subtracted from the current value, depending on the operation. The minimum value for data retention is 0 and the maximum value is 87600 (ten years).
        public let dataRetentionChangeInHours: Int
        /// Indicates whether you want to increase or decrease the retention period.
        public let operation: UpdateDataRetentionOperation
        /// The Amazon Resource Name (ARN) of the stream whose retention period you want to change.
        public let streamARN: String?
        /// The name of the stream whose retention period you want to change.
        public let streamName: String?

        @inlinable
        public init(currentVersion: String, dataRetentionChangeInHours: Int, operation: UpdateDataRetentionOperation, streamARN: String? = nil, streamName: String? = nil) {
            self.currentVersion = currentVersion
            self.dataRetentionChangeInHours = dataRetentionChangeInHours
            self.operation = operation
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, max: 64)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, min: 1)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, pattern: "^[a-zA-Z0-9]+$")
            try self.validate(self.dataRetentionChangeInHours, name: "dataRetentionChangeInHours", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case currentVersion = "CurrentVersion"
            case dataRetentionChangeInHours = "DataRetentionChangeInHours"
            case operation = "Operation"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct UpdateDataRetentionOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateImageGenerationConfigurationInput: AWSEncodableShape {
        /// The structure that contains the information required for the KVS images delivery. If the structure is null, the configuration will be deleted from the stream.
        public let imageGenerationConfiguration: ImageGenerationConfiguration?
        /// The Amazon Resource Name (ARN) of the Kinesis video stream from where you want to update the image generation configuration. You must specify either the StreamName  or the StreamARN.
        public let streamARN: String?
        /// The name of the stream from which to update the image generation configuration. You must specify either the StreamName or the StreamARN.
        public let streamName: String?

        @inlinable
        public init(imageGenerationConfiguration: ImageGenerationConfiguration? = nil, streamARN: String? = nil, streamName: String? = nil) {
            self.imageGenerationConfiguration = imageGenerationConfiguration
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.imageGenerationConfiguration?.validate(name: "\(name).imageGenerationConfiguration")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case imageGenerationConfiguration = "ImageGenerationConfiguration"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct UpdateImageGenerationConfigurationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateMediaStorageConfigurationInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the channel.
        public let channelARN: String
        /// A structure that encapsulates, or contains, the media storage configuration properties.
        public let mediaStorageConfiguration: MediaStorageConfiguration

        @inlinable
        public init(channelARN: String, mediaStorageConfiguration: MediaStorageConfiguration) {
            self.channelARN = channelARN
            self.mediaStorageConfiguration = mediaStorageConfiguration
        }

        public func validate(name: String) throws {
            try self.validate(self.channelARN, name: "channelARN", parent: name, max: 1024)
            try self.validate(self.channelARN, name: "channelARN", parent: name, min: 1)
            try self.validate(self.channelARN, name: "channelARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.mediaStorageConfiguration.validate(name: "\(name).mediaStorageConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case mediaStorageConfiguration = "MediaStorageConfiguration"
        }
    }

    public struct UpdateMediaStorageConfigurationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateNotificationConfigurationInput: AWSEncodableShape {
        /// The structure containing the information required for notifications. If the structure is null, the configuration will be deleted from the stream.
        public let notificationConfiguration: NotificationConfiguration?
        /// The Amazon Resource Name (ARN) of the Kinesis video stream from where you want to update the notification configuration. You must specify either the StreamName or the StreamARN.
        public let streamARN: String?
        /// The name of the stream from which to update the notification configuration. You must specify either the StreamName or the StreamARN.
        public let streamName: String?

        @inlinable
        public init(notificationConfiguration: NotificationConfiguration? = nil, streamARN: String? = nil, streamName: String? = nil) {
            self.notificationConfiguration = notificationConfiguration
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.notificationConfiguration?.validate(name: "\(name).notificationConfiguration")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case notificationConfiguration = "NotificationConfiguration"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct UpdateNotificationConfigurationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateSignalingChannelInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the signaling channel that you want to update.
        public let channelARN: String
        /// The current version of the signaling channel that you want to update.
        public let currentVersion: String
        /// The structure containing the configuration for the SINGLE_MASTER type of the signaling channel that you want to update.
        public let singleMasterConfiguration: SingleMasterConfiguration?

        @inlinable
        public init(channelARN: String, currentVersion: String, singleMasterConfiguration: SingleMasterConfiguration? = nil) {
            self.channelARN = channelARN
            self.currentVersion = currentVersion
            self.singleMasterConfiguration = singleMasterConfiguration
        }

        public func validate(name: String) throws {
            try self.validate(self.channelARN, name: "channelARN", parent: name, max: 1024)
            try self.validate(self.channelARN, name: "channelARN", parent: name, min: 1)
            try self.validate(self.channelARN, name: "channelARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, max: 64)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, min: 1)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, pattern: "^[a-zA-Z0-9]+$")
            try self.singleMasterConfiguration?.validate(name: "\(name).singleMasterConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case channelARN = "ChannelARN"
            case currentVersion = "CurrentVersion"
            case singleMasterConfiguration = "SingleMasterConfiguration"
        }
    }

    public struct UpdateSignalingChannelOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateStreamInput: AWSEncodableShape {
        /// The version of the stream whose metadata you want to update.
        public let currentVersion: String
        /// The name of the device that is writing to the stream.   In the current implementation, Kinesis Video Streams does not use this name.
        public let deviceName: String?
        /// The stream's media type. Use MediaType to specify the type of content that the stream contains to the consumers of the stream. For more information about media types, see Media Types. If you choose to specify the MediaType, see Naming Requirements. To play video on the console, you must specify the correct video type. For example, if the video in the stream is H.264, specify video/h264 as the MediaType.
        public let mediaType: String?
        /// The ARN of the stream whose metadata you want to update.
        public let streamARN: String?
        /// The name of the stream whose metadata you want to update. The stream name is an identifier for the stream, and must be unique for each account and region.
        public let streamName: String?

        @inlinable
        public init(currentVersion: String, deviceName: String? = nil, mediaType: String? = nil, streamARN: String? = nil, streamName: String? = nil) {
            self.currentVersion = currentVersion
            self.deviceName = deviceName
            self.mediaType = mediaType
            self.streamARN = streamARN
            self.streamName = streamName
        }

        public func validate(name: String) throws {
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, max: 64)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, min: 1)
            try self.validate(self.currentVersion, name: "currentVersion", parent: name, pattern: "^[a-zA-Z0-9]+$")
            try self.validate(self.deviceName, name: "deviceName", parent: name, max: 128)
            try self.validate(self.deviceName, name: "deviceName", parent: name, min: 1)
            try self.validate(self.deviceName, name: "deviceName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.mediaType, name: "mediaType", parent: name, max: 128)
            try self.validate(self.mediaType, name: "mediaType", parent: name, min: 1)
            try self.validate(self.mediaType, name: "mediaType", parent: name, pattern: "^[\\w\\-\\.\\+]+/[\\w\\-\\.\\+]+(,[\\w\\-\\.\\+]+/[\\w\\-\\.\\+]+)*$")
            try self.validate(self.streamARN, name: "streamARN", parent: name, max: 1024)
            try self.validate(self.streamARN, name: "streamARN", parent: name, min: 1)
            try self.validate(self.streamARN, name: "streamARN", parent: name, pattern: "^arn:[a-z\\d-]+:kinesisvideo:[a-z0-9-]+:[0-9]+:[a-z]+/[a-zA-Z0-9_.-]+/[0-9]+$")
            try self.validate(self.streamName, name: "streamName", parent: name, max: 256)
            try self.validate(self.streamName, name: "streamName", parent: name, min: 1)
            try self.validate(self.streamName, name: "streamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case currentVersion = "CurrentVersion"
            case deviceName = "DeviceName"
            case mediaType = "MediaType"
            case streamARN = "StreamARN"
            case streamName = "StreamName"
        }
    }

    public struct UpdateStreamOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UploaderConfig: AWSEncodableShape & AWSDecodableShape {
        /// The configuration that consists of the ScheduleExpression and the  DurationInMinutes details that specify the scheduling to record from a camera, or local media file, onto the Edge Agent. If the ScheduleConfig is not provided in this UploaderConfig, then the Edge Agent will upload at regular intervals (every 1 hour).
        public let scheduleConfig: ScheduleConfig

        @inlinable
        public init(scheduleConfig: ScheduleConfig) {
            self.scheduleConfig = scheduleConfig
        }

        public func validate(name: String) throws {
            try self.scheduleConfig.validate(name: "\(name).scheduleConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case scheduleConfig = "ScheduleConfig"
        }
    }
}

// MARK: - Errors

/// Error enum for KinesisVideo
public struct KinesisVideoErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case accountChannelLimitExceededException = "AccountChannelLimitExceededException"
        case accountStreamLimitExceededException = "AccountStreamLimitExceededException"
        case clientLimitExceededException = "ClientLimitExceededException"
        case deviceStreamLimitExceededException = "DeviceStreamLimitExceededException"
        case invalidArgumentException = "InvalidArgumentException"
        case invalidDeviceException = "InvalidDeviceException"
        case invalidResourceFormatException = "InvalidResourceFormatException"
        case noDataRetentionException = "NoDataRetentionException"
        case notAuthorizedException = "NotAuthorizedException"
        case resourceInUseException = "ResourceInUseException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case streamEdgeConfigurationNotFoundException = "StreamEdgeConfigurationNotFoundException"
        case tagsPerResourceExceededLimitException = "TagsPerResourceExceededLimitException"
        case versionMismatchException = "VersionMismatchException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize KinesisVideo
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have required permissions to perform this operation.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// You have reached the maximum limit of active signaling channels for this Amazon Web Services account in this region.
    public static var accountChannelLimitExceededException: Self { .init(.accountChannelLimitExceededException) }
    /// The number of streams created for the account is too high.
    public static var accountStreamLimitExceededException: Self { .init(.accountStreamLimitExceededException) }
    /// Kinesis Video Streams has throttled the request because you have exceeded the limit of allowed client calls. Try making the call later.
    public static var clientLimitExceededException: Self { .init(.clientLimitExceededException) }
    /// Not implemented.
    public static var deviceStreamLimitExceededException: Self { .init(.deviceStreamLimitExceededException) }
    /// The value for this input parameter is invalid.
    public static var invalidArgumentException: Self { .init(.invalidArgumentException) }
    /// Not implemented.
    public static var invalidDeviceException: Self { .init(.invalidDeviceException) }
    /// The format of the StreamARN is invalid.
    public static var invalidResourceFormatException: Self { .init(.invalidResourceFormatException) }
    /// The Stream data retention in hours is equal to zero.
    public static var noDataRetentionException: Self { .init(.noDataRetentionException) }
    /// The caller is not authorized to perform this operation.
    public static var notAuthorizedException: Self { .init(.notAuthorizedException) }
    /// When the input StreamARN or ChannelARN in CLOUD_STORAGE_MODE is already mapped to a different Kinesis Video Stream resource, or if the provided input StreamARN or ChannelARN is not in Active status, try one of the following :    The DescribeMediaStorageConfiguration API to determine what the stream given channel is mapped to.     The DescribeMappedResourceConfiguration API to determine the channel that the given stream is mapped to.     The DescribeStream or DescribeSignalingChannel API to determine the status of the resource.
    public static var resourceInUseException: Self { .init(.resourceInUseException) }
    /// Amazon Kinesis Video Streams can't find the stream that you specified.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The Exception rendered when the Amazon Kinesis Video Stream can't find a stream's edge configuration that you specified.
    public static var streamEdgeConfigurationNotFoundException: Self { .init(.streamEdgeConfigurationNotFoundException) }
    /// You have exceeded the limit of tags that you can associate with the resource. A Kinesis video stream can support up to 50 tags.
    public static var tagsPerResourceExceededLimitException: Self { .init(.tagsPerResourceExceededLimitException) }
    /// The stream version that you specified is not the latest version. To get the latest version, use the DescribeStream API.
    public static var versionMismatchException: Self { .init(.versionMismatchException) }
}

extension KinesisVideoErrorType: Equatable {
    public static func == (lhs: KinesisVideoErrorType, rhs: KinesisVideoErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension KinesisVideoErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
